#include "xmppcore/presenceparserfactory.h"
#include "xmppcore/presence.h"
#include "xmppcore/parsingutils.h"

namespace yoohoo_xmppcore {

const QString PresenceParser::PATH_PRESENCE_STATUS = "presence/status";
const QString PresenceParser::PATH_PRESENCE_SHOW = "presence/show";
const QString PresenceParser::PATH_PRESENCE_PRIORITY = "presence/priority";
const QString PresenceParser::PATH_PRESENCE = "presence";

PresenceParser::PresenceParser() : _presence(0) {
}

Stanza* PresenceParser::stanza() {
	if (_presence == 0) {
		_presence = new Presence;
	}

	return _presence;
}

bool PresenceParser::doProcessAttributes(QString path, QList<ParsingAttribute> attributes) {
	if (PATH_PRESENCE_STATUS == path) {
		QString xmlLang;
		if (ParsingUtils::readXmlLang(attributes, xmlLang))
			_status.setXmlLang(xmlLang);
	} else if (PATH_PRESENCE_SHOW != path && PATH_PRESENCE_PRIORITY != path) {
		return false;
	} else if (attributes.size() != 0) {
		return false;
	}

	return true;
}

bool PresenceParser::processText(QString path, QString text) {
	if (PATH_PRESENCE_SHOW == path) {
		if (_presence->presenceShow() != Presence::PresenceShowNone) {
			return false;
		}

		if (text.isEmpty()) {
			_presence->setPresenceShow(Presence::PresenceShowNone);
		} else if ("xa" == text) {
			_presence->setPresenceShow(Presence::PresenceShowXA);
		} else if ("dnd" == text) {
			_presence->setPresenceShow(Presence::PresenceShowDND);
		} else if ("away" == text) {
			_presence->setPresenceShow(Presence::PresenceShowAway);
		} else if ("chat" == text) {
			_presence->setPresenceShow(Presence::PresenceShowChat);
		} else {
			return false;
		}
	} else if (PATH_PRESENCE_STATUS == path) {
		_status.setText(text);
		_presence->status().append(_status);
		_status = XmlLangText();
	} else if (PATH_PRESENCE_PRIORITY == path) {
		if (_presence->priority() != Presence::PRIORITY_NOT_SET) {
			return false;
		}

		bool ok;
		int priority = text.toInt(&ok);
		if (!ok) {
			return false;
		}
		_presence->setPriority(priority);

		// (rfc3921 2.2.2.3)
		if (_presence->priority() < -128 || _presence->priority() > 127) {
			return false;
		}
	} else if (PATH_PRESENCE == path) {
		if (!text.isEmpty())
			return false;
	} else {
		return false;
	}

	return true;
}

bool PresenceParser::setType(QString sType) {
	if (sType.isEmpty()) {
		_presence->setPresenceType(Presence::PresenceTypeNone);
	} else if ("available" == sType) {
		_presence->setPresenceType(Presence::PresenceTypeAvailable);
	} else if ("unavailable" == sType) {
		_presence->setPresenceType(Presence::PresenceTypeUnavailable);
	} else if ("subscribe" == sType) {
		_presence->setPresenceType(Presence::PresenceTypeSubscribe);
	} else if ("subscribed" == sType) {
		_presence->setPresenceType(Presence::PresenceTypeSubscribed);
	} else if ("unsubscribe" == sType) {
		_presence->setPresenceType(Presence::PresenceTypeUnavailable);
	} else if ("unsubscribed" == sType) {
		_presence->setPresenceType(Presence::PresenceTypeUnsubscribed);
	} else {
		return false;
	}

	return true;
}

ProtocolKey PresenceParserFactory::protocolKey() {
	return Presence::PROTOCOL_KEY;
}

XmppParser* PresenceParserFactory::createParser() {
	return new PresenceParser;
}

}
